<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>Document</title>
	</head>
	<body>
		<script type="text/javascript" >

			let data = {
				name:'尚硅谷',
				address:'北京',
			}

		// Object.defineProperty(data,'name',{
		// 	get(){
		// 		return data.name //数据代理不能直接在原数据上进行 这里逻辑是当你调用时返回data.name 自己又调用了自己 又调用了这个函数
		// 	},
		// 	set(val){
		// 		data.name=val
		// 	}
		// })


			//对于底层而言创建一个监视的实例对象，用于监视data中属性的变化
			// 这里的data就理解为创建vm时候的配置数据data
			const obs = new Observer(data)		
			console.log(obs)	

			//准备一个vm实例对象
			let vm = {}
			vm._data = data = obs //将配置数据data代理到_data中

			function Observer(obj){
				//汇总对象中所有的属性形成一个数组
				const keys = Object.keys(obj)
				//遍历
				keys.forEach((k)=>{
					Object.defineProperty(this,k,{
						get(){
							return obj[k]
						},
						set(val){
							console.log(`${k}被改了，我要去解析模板，生成虚拟DOM.....我要开始忙了`)
							obj[k] = val
						}
					})
				})
			}

		// vm比这个完善的点在于1、这个需要vm._data.name修改 实际上vue提供vm.name
		// 2、data内部再定义一个对象如data{{b:1},'name':'尚硅谷'} b是无法跟踪的

		// 总结 在创建vm实例的时候传递的data是会在底层进行数据代理到vm实例对象上,即将data配置项的数据代理到vm._data上，然后再代理到vm的属性如vm.name上

		</script>
	</body>
</html>